package org.zjt.lock;


import java.util.concurrent.atomic.AtomicReference;

public class CLHLock  {
    // 结尾
    AtomicReference<QNode> tail = new AtomicReference<QNode>(new QNode());

    // 前一个线程节点
    ThreadLocal<QNode> myPred;

    //当前线程节点
    ThreadLocal<QNode> myNode;

    public CLHLock() {
        tail = new AtomicReference<QNode>(new QNode());
        myNode = new ThreadLocal<QNode>() {
            protected QNode initialValue() {
                return new QNode();
            }
        };
        myPred = new ThreadLocal<QNode>() {
            protected QNode initialValue() {
                return null;
            }
        };
    }

    public void lock() {
        QNode qnode = myNode.get();
        qnode.locked = true;

        // 得到上一个获取资源lock的线程，并追加自己node
        QNode pred = tail.getAndSet(qnode);
        myPred.set(pred);
        //自旋等待前一个线程node释放锁： while循环，这 是在等待前趋结点的locked域变为false，这是一个自旋等待的过程
        while (pred.locked) {
        }
    }

    public void unlock() {
        //当前的线程lock资源节点释放。
        QNode qnode = myNode.get();
        qnode.locked = false;

        //剔除当前节点，设置为前一个节点。
        myNode.set(myPred.get());
    }
}

 class QNode {
     protected boolean locked;
}